using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;

namespace demo.Tool
{
    /// <summary>
    /// 本地数据帮助类
    /// 用于存储当日的本地数据（使用XML文件存储）
    /// </summary>
    public class LocalDbHelper
    {
        private static string dataFilePath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "LocalData.xml");
        private static readonly object lockObject = new object();

        /// <summary>
        /// 公共初始化方法
        /// </summary>
        public static void Initialize()
        {
            InitializeDatabase();
        }

        /// <summary>
        /// 初始化XML数据文件
        /// </summary>
        private static void InitializeDatabase()
        {
            lock (lockObject)
            {
                if (!File.Exists(dataFilePath))
                {
                    try
                    {
                        var doc = new XDocument(
                            new XElement("LocalData",
                                new XElement("DailyData")
                            )
                        );
                        doc.Save(dataFilePath);
                        Console.WriteLine("XML数据文件已创建");
                    }
                    catch (Exception ex)
                    {
                        throw new Exception($"创建XML数据文件失败: {ex.Message}");
                    }
                }
                else
                {
                    // 检查并添加DailyData节点（向后兼容）
                    try
                    {
                        var doc = XDocument.Load(dataFilePath);
                        if (doc.Root.Element("DailyData") == null)
                        {
                            doc.Root.Add(new XElement("DailyData"));
                            doc.Save(dataFilePath);
                            Console.WriteLine("已添加DailyData节点");
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"更新XML结构失败: {ex.Message}");
                    }
                }
            }
        }

        /// <summary>
        /// 保存或更新数据
        /// </summary>
        /// <param name="dataType">数据类型</param>
        /// <param name="dataKey">数据键</param>
        /// <param name="dataValue">数据值</param>
        /// <returns>是否成功</returns>
        public static bool SaveData(string dataType, string dataKey, string dataValue)
        {
            try
            {
                lock (lockObject)
                {
                    InitializeDatabase(); // 确保文件存在
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    // 查找是否已存在相同的数据
                    var existingElement = dailyDataElement.Elements("Data")
                        .FirstOrDefault(e => e.Attribute("Type")?.Value == dataType && 
                                           e.Attribute("Key")?.Value == dataKey);
                    
                    if (existingElement != null)
                    {
                        // 更新现有数据
                        existingElement.Attribute("Value").Value = dataValue ?? "";
                        existingElement.Attribute("UpdateTime").Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    }
                    else
                    {
                        // 添加新数据
                        var newElement = new XElement("Data",
                            new XAttribute("Type", dataType ?? ""),
                            new XAttribute("Key", dataKey ?? ""),
                            new XAttribute("Value", dataValue ?? ""),
                            new XAttribute("CreateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
                            new XAttribute("UpdateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
                        );
                        dailyDataElement.Add(newElement);
                    }
                    
                    doc.Save(dataFilePath);
                }
                return true;
            }
            catch (Exception ex)
            {
                // 可以记录日志
                Console.WriteLine($"保存本地数据失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 获取数据
        /// </summary>
        /// <param name="dataType">数据类型</param>
        /// <param name="dataKey">数据键</param>
        /// <returns>数据值</returns>
        public static string GetData(string dataType, string dataKey)
        {
            try
            {
                lock (lockObject)
                {
                    if (!File.Exists(dataFilePath))
                        return null;
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    var element = dailyDataElement.Elements("Data")
                        .FirstOrDefault(e => e.Attribute("Type")?.Value == dataType && 
                                           e.Attribute("Key")?.Value == dataKey);
                    
                    return element?.Attribute("Value")?.Value;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取本地数据失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 获取指定类型的所有数据
        /// </summary>
        /// <param name="dataType">数据类型</param>
        /// <returns>数据字典</returns>
        public static Dictionary<string, string> GetDataByType(string dataType)
        {
            var result = new Dictionary<string, string>();
            
            try
            {
                lock (lockObject)
                {
                    if (!File.Exists(dataFilePath))
                        return result;
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    var elements = dailyDataElement.Elements("Data")
                        .Where(e => e.Attribute("Type")?.Value == dataType)
                        .OrderByDescending(e => DateTime.Parse(e.Attribute("UpdateTime")?.Value ?? DateTime.MinValue.ToString()));
                    
                    foreach (var element in elements)
                    {
                        string key = element.Attribute("Key")?.Value ?? "";
                        string value = element.Attribute("Value")?.Value ?? "";
                        if (!result.ContainsKey(key))
                        {
                            result[key] = value;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取本地数据失败: {ex.Message}");
            }
            
            return result;
        }

        /// <summary>
        /// 删除数据
        /// </summary>
        /// <param name="dataType">数据类型</param>
        /// <param name="dataKey">数据键</param>
        /// <returns>是否成功</returns>
        public static bool DeleteData(string dataType, string dataKey)
        {
            try
            {
                lock (lockObject)
                {
                    if (!File.Exists(dataFilePath))
                        return false;
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    var elementToRemove = dailyDataElement.Elements("Data")
                        .FirstOrDefault(e => e.Attribute("Type")?.Value == dataType && 
                                           e.Attribute("Key")?.Value == dataKey);
                    
                    if (elementToRemove != null)
                    {
                        elementToRemove.Remove();
                        doc.Save(dataFilePath);
                        return true;
                    }
                    
                    return false;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"删除本地数据失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 清理指定天数之前的数据
        /// </summary>
        /// <param name="days">保留天数</param>
        /// <returns>清理的记录数</returns>
        public static int CleanOldData(int days = 7)
        {
            try
            {
                lock (lockObject)
                {
                    if (!File.Exists(dataFilePath))
                        return 0;
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    var cutoffDate = DateTime.Now.AddDays(-days);
                    var elementsToRemove = dailyDataElement.Elements("Data")
                        .Where(e => 
                        {
                            var createTimeStr = e.Attribute("CreateTime")?.Value;
                            if (DateTime.TryParse(createTimeStr, out DateTime createTime))
                            {
                                return createTime < cutoffDate;
                            }
                            return false;
                        })
                        .ToList();
                    
                    int removedCount = elementsToRemove.Count;
                    foreach (var element in elementsToRemove)
                    {
                        element.Remove();
                    }
                    
                    if (removedCount > 0)
                    {
                        doc.Save(dataFilePath);
                    }
                    
                    return removedCount;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"清理旧数据失败: {ex.Message}");
                return 0;
            }
        }

        /// <summary>
        /// 获取数据文件大小
        /// </summary>
        /// <returns>文件大小（字节）</returns>
        public static long GetDatabaseSize()
        {
            try
            {
                if (File.Exists(dataFilePath))
                {
                    return new FileInfo(dataFilePath).Length;
                }
                return 0;
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 保存患者访问数据（专用于定时任务数据）
        /// </summary>
        /// <param name="patientData">患者数据JSON字符串</param>
        /// <returns>是否成功保存</returns>
        public static bool SavePatientVisitData(string patientData)
        {
            try
            {
                // 解析JSON数据
                var jsonData = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(patientData);
                if (jsonData?.data?.outP_VISIT_ID == null)
                {
                    Console.WriteLine("数据格式错误：缺少outP_VISIT_ID");
                    return false;
                }

                string outpVisitId = jsonData.data.outP_VISIT_ID.ToString();
                string today = DateTime.Now.ToString("yyyy-MM-dd");
                
                lock (lockObject)
                {
                    InitializeDatabase();
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    // 检查是否已存在相同的outP_VISIT_ID
                    var existingElement = dailyDataElement.Elements("PatientVisit")
                        .FirstOrDefault(e => e.Attribute("outP_VISIT_ID")?.Value == outpVisitId);
                    
                    if (existingElement != null)
                    {
                        Console.WriteLine($"数据已存在，outP_VISIT_ID: {outpVisitId}");
                        return false; // 不允许重复数据
                    }
                    
                    // 创建新的患者访问记录
                    var newElement = new XElement("PatientVisit",
                        new XAttribute("outP_VISIT_ID", jsonData.data.outP_VISIT_ID?.ToString() ?? ""),
                        new XAttribute("patienT_ID", jsonData.data.patienT_ID?.ToString() ?? ""),
                        new XAttribute("patI_NAME", jsonData.data.patI_NAME?.ToString() ?? ""),
                        new XAttribute("outP_SPECIAL_NAME", jsonData.data.outP_SPECIAL_NAME?.ToString() ?? ""),
                        new XAttribute("outP_DATE", jsonData.data.outP_DATE?.ToString() ?? ""),
                        new XAttribute("visiT_ID", jsonData.data.visiT_ID?.ToString() ?? ""),
                        new XAttribute("admissioN_DOCTOR", jsonData.data.admissioN_DOCTOR?.ToString() ?? ""),
                        new XAttribute("doctoR_VS_OUTP_VISIT_ID", jsonData.data.doctoR_VS_OUTP_VISIT_ID?.ToString() ?? ""),
                        new XAttribute("qR_CODE", jsonData.data.qR_CODE?.ToString() ?? ""),
                        new XAttribute("registratioN_FEE_STATUS", jsonData.data.registratioN_FEE_STATUS?.ToString() ?? ""),
                        new XAttribute("paT_LEVEL", jsonData.data.paT_LEVEL?.ToString() ?? ""),
                        new XAttribute("liS_COUNT", jsonData.data.liS_COUNT?.ToString() ?? ""),
                        new XAttribute("exaM_COUNT", jsonData.data.exaM_COUNT?.ToString() ?? ""),
                        new XAttribute("reaD_FLAG", jsonData.data.reaD_FLAG?.ToString() ?? ""),
                        new XAttribute("ordeR_NAMES", jsonData.data.ordeR_NAMES?.ToString() ?? ""),
                        new XAttribute("SaveDate", today),
                        new XAttribute("CreateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
                        new XAttribute("Success", jsonData.success?.ToString() ?? "false"),
                        new XAttribute("Message", jsonData.message?.ToString() ?? "")
                    );
                    
                    dailyDataElement.Add(newElement);
                    doc.Save(dataFilePath);
                    
                    Console.WriteLine($"患者访问数据已保存，outP_VISIT_ID: {outpVisitId}");
                    return true;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"保存患者访问数据失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 获取当日所有患者访问数据
        /// </summary>
        /// <returns>患者访问数据列表</returns>
        public static List<Dictionary<string, string>> GetTodayPatientVisitData()
        {
            var result = new List<Dictionary<string, string>>();
            string today = DateTime.Now.ToString("yyyy-MM-dd");
            
            try
            {
                lock (lockObject)
                {
                    if (!File.Exists(dataFilePath))
                        return result;
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    var elements = dailyDataElement.Elements("PatientVisit")
                        .Where(e => e.Attribute("SaveDate")?.Value == today)
                        .OrderByDescending(e => DateTime.Parse(e.Attribute("CreateTime")?.Value ?? DateTime.MinValue.ToString()));
                    
                    foreach (var element in elements)
                    {
                        var patientData = new Dictionary<string, string>();
                        foreach (var attr in element.Attributes())
                        {
                            patientData[attr.Name.LocalName] = attr.Value;
                        }
                        result.Add(patientData);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取当日患者访问数据失败: {ex.Message}");
            }
            
            return result;
        }

        /// <summary>
        /// 根据outP_VISIT_ID获取患者访问数据
        /// </summary>
        /// <param name="outpVisitId">患者访问ID</param>
        /// <returns>患者数据字典</returns>
        public static Dictionary<string, string> GetPatientVisitDataById(string outpVisitId)
        {
            try
            {
                lock (lockObject)
                {
                    if (!File.Exists(dataFilePath))
                        return null;
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    var element = dailyDataElement.Elements("PatientVisit")
                        .FirstOrDefault(e => e.Attribute("outP_VISIT_ID")?.Value == outpVisitId);
                    
                    if (element != null)
                    {
                        var patientData = new Dictionary<string, string>();
                        foreach (var attr in element.Attributes())
                        {
                            patientData[attr.Name.LocalName] = attr.Value;
                        }
                        return patientData;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取患者访问数据失败: {ex.Message}");
            }
            
            return null;
        }

        /// <summary>
        /// 检查outP_VISIT_ID是否已存在
        /// </summary>
        /// <param name="outpVisitId">患者访问ID</param>
        /// <returns>是否存在</returns>
        public static bool IsPatientVisitIdExists(string outpVisitId)
        {
            try
            {
                lock (lockObject)
                {
                    if (!File.Exists(dataFilePath))
                        return false;
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    return dailyDataElement.Elements("PatientVisit")
                        .Any(e => e.Attribute("outP_VISIT_ID")?.Value == outpVisitId);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"检查患者访问ID失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 清理非当日的患者访问数据
        /// </summary>
        /// <returns>清理的记录数</returns>
        public static int CleanNonTodayPatientData()
        {
            string today = DateTime.Now.ToString("yyyy-MM-dd");
            
            try
            {
                lock (lockObject)
                {
                    if (!File.Exists(dataFilePath))
                        return 0;
                    
                    var doc = XDocument.Load(dataFilePath);
                    var dailyDataElement = doc.Root.Element("DailyData");
                    
                    var elementsToRemove = dailyDataElement.Elements("PatientVisit")
                        .Where(e => e.Attribute("SaveDate")?.Value != today)
                        .ToList();
                    
                    int removedCount = elementsToRemove.Count;
                    foreach (var element in elementsToRemove)
                    {
                        element.Remove();
                    }
                    
                    if (removedCount > 0)
                    {
                        doc.Save(dataFilePath);
                        Console.WriteLine($"已清理 {removedCount} 条非当日患者数据");
                    }
                    
                    return removedCount;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"清理非当日患者数据失败: {ex.Message}");
                return 0;
            }
        }

        /// <summary>
        /// 清空所有本地数据
        /// </summary>
        /// <returns>是否成功</returns>
        public static bool ClearAllData()
        {
            try
            {
                lock (lockObject)
                {
                    // 重新创建空的XML文件
                    var doc = new XDocument(
                        new XElement("LocalData",
                            new XElement("DailyData")
                        )
                    );
                    doc.Save(dataFilePath);
                    Console.WriteLine("已清空所有本地数据");
                    return true;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"清空本地数据失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 获取当日患者访问数据统计
        /// </summary>
        /// <returns>统计信息</returns>
        public static Dictionary<string, int> GetTodayPatientStatistics()
        {
            var stats = new Dictionary<string, int>
            {
                ["TotalCount"] = 0,
                ["ReadCount"] = 0,
                ["UnreadCount"] = 0,
                ["WithLisCount"] = 0,
                ["WithExamCount"] = 0
            };
            
            try
            {
                var todayData = GetTodayPatientVisitData();
                stats["TotalCount"] = todayData.Count;
                
                foreach (var patient in todayData)
                {
                    if (patient.ContainsKey("reaD_FLAG") && patient["reaD_FLAG"] == "1")
                        stats["ReadCount"]++;
                    else
                        stats["UnreadCount"]++;
                    
                    if (patient.ContainsKey("liS_COUNT") && int.TryParse(patient["liS_COUNT"], out int lisCount) && lisCount > 0)
                        stats["WithLisCount"]++;
                    
                    if (patient.ContainsKey("exaM_COUNT") && int.TryParse(patient["exaM_COUNT"], out int examCount) && examCount > 0)
                        stats["WithExamCount"]++;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取患者统计数据失败: {ex.Message}");
            }
            
            return stats;
        }
    }
}